<?php declare(strict_types=1);

namespace App\Http\Middleware;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Swoft\Bean\Annotation\Mapping\Bean;
use Swoft\Http\Server\Contract\MiddlewareInterface;
use Swoft\Redis\Redis;

/**
 * @Bean()
 */
class ControllerMiddleware implements MiddlewareInterface
{
        /**
        * Process an incoming server request.
        *
        * @param ServerRequestInterface $request
        * @param RequestHandlerInterface $handler
        *
        * @return ResponseInterface
        * @inheritdoc
        */
        public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
        {
                if ('OPTIONS' === $request->getMethod()) {
                        $response = response();
                        return $this->configResponse($response);
                }
                $request->timestamp = time();
                $strCheckFrequentRequestName = md5(ip() . userAgent() . route(1) . query()) . '_frequent_request_validation';
                $booleCheckFrequentRequest = Redis::get($strCheckFrequentRequestName);
                if ($booleCheckFrequentRequest) {
                        $response = response();
                        return $this->configResponse($response)->withStatus(500)->withContent('请勿频繁请求');
                }
                Redis::set($strCheckFrequentRequestName, true, 1);
                $response = $handler->handle($request);
                Redis::del($strCheckFrequentRequestName);
                if ($request->getHeader('origin')) return $this->configResponse($response);
                return $response;
        }
        
        private function configResponse(ResponseInterface $response)
        {
                return $response
                        ->withHeader('Access-Control-Allow-Origin', request()->getHeader('origin')[0])
                        ->withHeader('Access-Control-Allow-Credentials', 'true')
                        ->withHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization, Token')
                        ->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, HEAD, PATCH, OPTIONS');
        }
}